<template>
	<view class="uni-select-lay" :style="{ 'z-index': zindex }">
		<input type="text" :name="name" v-model="value" class="uni-select-input" />

		<view class="mapFilter">
			<image
				src="/static/images/watch/map1.png"
				class="mapIcon"
				mode="widthFix"
			></image>
			<view class="filter-lable">检测点</view>
			<view class="line"></view>

			<view class="iptBox">
				<view class="uni-select-lay-select" :class="{ active: active }">
					<!-- 禁用mask -->
					<view class="uni-disabled" v-if="disabled"></view>
					<!-- 禁用mask -->
					<!-- 清空 -->
					<view
						class="uni-select-lay-input-close"
						v-if="changevalue != '' && this.active"
					>
						<text @click="removevalue"></text>
					</view>
					<!-- 清空 -->
					<input
						type="text"
						class="uni-select-lay-input"
						:class="{ active: changevalue != '' && changevalue != placeholder }"
						v-model="changevalue"
						:disabled="disabled"
						:placeholder="placeholder"
						@focus="unifocus"
						@input="intchange"
					/>
				</view>
				<u-icon name="arrow-down" size="18px" color="#999999"></u-icon>
			</view>
		</view>

		<!-- 下拉框展示内容 :单选-->
		<view
			v-if="!multiple"
			class="uni-select-lay-options"
			:class="
				optionsDirection === 'top'
					? 'uni-select-lay-options-top'
					: 'uni-select-lay-options-bottom'
			"
			v-show="active"
		>
			<!-- 加载中 -->
			<template v-if="loading">
				<view class="uni-select-lay-item" style="color: #777777;">
					<image
						src=""
						mode="widthFix"
						style="width: 16px;height: 16px;margin-right: 5px;"
						class=".rotating__animation"
					></image>
					<text>{{ loadingText }}</text>
				</view>
			</template>
			<!-- 加载中 -->
			<!-- 未输入是显示内容 -->
			<template v-else-if="!changes">
				<view
					class="uni-select-lay-item"
					:class="{ active: value == '' }"
					@click="selectitem(-1, null)"
				>
					{{ placeholder }}
				</view>
				<view
					class="uni-select-lay-item"
					:class="{ active: value == item[svalue] }"
					v-for="(item, index) in options"
					:key="index"
					@click="selectitem(index, item)"
				>
					{{ item[slabel] }}
				</view>
			</template>
			<!-- 未输入是显示内容 -->
			<!-- 搜索时显示内容 -->
			<template v-else>
				<template v-if="vlist.length > 0">
					<view
						class="uni-select-lay-item"
						:class="{ active: value == item[svalue] }"
						v-for="(item, index) in vlist"
						:key="index"
						@click="selectitem(index, item)"
					>
						{{ item[slabel] }}
					</view>
				</template>
				<template v-else>
					<view class="nosearch">无匹配内容！</view>
				</template>
			</template>
			<!-- 搜索时显示内容 -->
		</view>
		<!-- 下拉框展示内容 :单选 -->
	</view>
</template>

<script>
/**
 * Select 下拉选择插件
 * @description  简单的下拉选择插件
 * @tutorial url https://ext.dcloud.net.cn/plugin?id=5627
 * @property {Boolean}  disabled =[true | false] 是否禁用(默认false)
 * @property {Number}  zindex 层级，默认999，防止多个组件一起使用是下拉栏穿透
 * @property {Array}  options	数据列表
 * @property {String}  optionsDirection	数据列表的位置（默认值bottom）
 * 	@value top 数据列表位于上方
 *  @value bottom 数据列表位于下方
 * @property {Boolean}  loading	是否加载中
 * @property {String}  loadingText	加载时提示文字
 * @property {Boolean}  multiple 是否多选（默认false）
 * @property {String} name input字段名
 * @property {String} value 默认展示的value值
 * @property {String} placeholder	无选项时展示的文字
 * @property {String} slabel	自定义列表中键值对应关系 (默认label)（键值对应label）
 * @property {String}  svalue  自定义列表中键值对应关系（默认value）(键值对应value)
 * @event {Function()} selectitem 点击选项时触发事件
 */
/**
 * 也参考了插件：https://ext.dcloud.net.cn/plugin?id=2868
 */
export default {
	name: 'luyj-select-lay',
	props: {
		// 是否禁用
		disabled: {
			type: Boolean,
			default: false
		},
		// 层级
		zindex: {
			type: Number,
			default: 999
		},
		// 数据列表
		options: {
			type: Array,
			default() {
				return [];
			}
		},
		// 数据列表的位置
		optionsDirection: {
			type: String,
			default: 'bottom'
		},
		// 是否加载中
		loading: {
			type: Boolean,
			default: false
		},
		// 加载提示文字
		loadingText: {
			type: String,
			default: '数据加载中……'
		},
		// 是否多选
		multiple: {
			type: Boolean,
			default: false
		},
		// input字段名
		name: {
			type: String,
			default: ''
		},
		// 默认展示value值
		value: {
			type: String,
			default: ''
		},
		// 无选项时展示文字
		placeholder: {
			type: String,
			default: '请选择'
		},
		// 自定义列表中键值对应关系label
		slabel: {
			type: String,
			default: 'label'
		},
		// 自定义列表中键值对应关系 value
		svalue: {
			type: String,
			default: 'value'
		}
	},
	data() {
		return {
			active: false, //组件是否激活，
			changevalue: '', //搜索框同步
			oldvalue: '', //数据回滚
			changes: false, //正在搜索
			vlist: [] //搜索框查询的列表
		};
	},
	// created之后，元素加载完毕
	mounted() {
		this.itemcheck();
	},
	watch: {
		//value改变
		value() {
			this.itemcheck();
		},
		//初始化数组
		options() {
			// 此处判断是否有初始value,存在则判断显示文字
			this.itemcheck();
		}
	},
	methods: {
		// 单选和多选的方式本身有相似性,这里先分开.后期再改.
		// ========================================= 单选 ============================================================
		/**
		 * 判断数组及当前active值
		 */
		itemcheck() {
			// 此处判断是否有初始value,存在则判断显示文字
			if (this.value != '') {
				// 展示plachhoder
				//判断数组
				if (this.options.length > 0) {
					this.options.forEach(item => {
						if (this.value == item[this.svalue]) {
							this.oldvalue = this.changevalue = item[this.slabel];
							return;
						}
					});
				}
			} else {
				this.oldvalue = this.changevalue = '';
			}
		},
		/**
		 * 点击组件
		 */
		select() {
			if (this.disabled) {
				return;
			}
			this.active = !this.active;
			if (this.active) {
				this.changes = false;
			} else {
				this.changevalue = this.oldvalue;
			}
		},
		/**
		 * 获得焦点
		 */
		unifocus() {
			if (this.disabled) {
				return;
			}
			this.active = true;
			this.changes = false;
		},
		/**
		 * 移除数据
		 */
		removevalue() {
			this.changes = false;
			this.changevalue = '';
		},
		/**
		 * value值改变
		 */
		intchange() {
			if (this.changevalue == '') {
				this.changes = false;
				return;
			}
			this.changes = true;
			this.vlist = this.options.filter(item => {
				return item[this.slabel].includes(this.changevalue);
			});
		},
		/** 点击组件列
		 * @param {Object} index 索引
		 * @param {Object} item	值
		 */
		selectitem(index, item) {
			this.active = false;
			this.$emit('selectitem', index, item);
		}
		// =============================================== 多选 =======================================================
	}
};
</script>

<style lang="scss" scoped>
.uni-select-lay {
	position: relative;
	z-index: 999;

	.uni-select-input {
		opacity: 0;
		position: absolute;
		z-index: -111;
	}

	// select部分
	.uni-select-lay-select {
		flex: 1;
		user-select: none;
		position: relative;
		z-index: 3;
		height: 36px;
		padding: 0 30px 0 10px;
		box-sizing: border-box;
		border-radius: 4px;
		// border: 1px solid rgb(229, 229, 229);
		display: flex;
		align-items: center;
		font-size: 14px;
		color: #999;

		.uni-disabled {
			position: absolute;
			left: 0;
			width: 100%;
			height: 100%;
			z-index: 19;
			cursor: no-drop;
		}

		// input 框的清除按钮
		.uni-select-lay-input-close {
			position: absolute;
			right: 35px;
			top: 0;
			height: 100%;
			width: 15px;
			display: flex;
			align-items: center;
			justify-content: center;
			z-index: 3;
			cursor: pointer;

			text {
				position: relative;
				background: #fff;
				width: 13px;
				height: 13px;
				border-radius: 50%;
				border: 1px solid #bbb;

				&::before,
				&::after {
					content: '';
					position: absolute;
					left: 20%;
					top: 50%;
					height: 1px;
					width: 60%;
					transform: rotate(45deg);
					background-color: #bbb;
				}

				&::after {
					transform: rotate(-45deg);
				}
			}
		}

		.uni-select-lay-input {
			font-size: 14px;
			color: #999;
			display: block;
			width: 98%;
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
			line-height: 30px;

			&.active {
				color: #333;
			}
		}

		.uni-select-lay-icon {
			cursor: pointer;
			position: absolute;
			right: 0;
			top: 0;
			height: 100%;
			width: 30px;
			display: flex;
			align-items: center;
			justify-content: center;

			&::before {
				content: '';
				width: 1px;
				height: 100%;
				position: absolute;
				left: 0;
				top: 0;
				background-color: #e5e5e5;
			}

			text {
				display: block;
				width: 0;
				height: 0;
				border-width: 12rpx 12rpx 0;
				border-style: solid;
				border-color: #bbb transparent transparent;
				transition: 0.3s;
			}
		}

		&.active .uni-select-lay-icon {
			text {
				transform: rotate(180deg);
			}
		}
	}

	// options部分
	.uni-select-lay-options {
		box-shadow: 0px 4rpx 13rpx 0px rgba(34, 23, 20, 0.1);
		user-select: none;
		position: absolute;
		left: 0;
		width: 100%;
		height: 500rpx;
		overflow-y: auto;
		border-radius: 4px;
		border: 1px solid rgb(229, 229, 229);
		background: #fff;
		padding: 5px 0;
		box-sizing: border-box;
		z-index: 9;

		.uni-select-lay-item {
			padding: 0 10px;
			box-sizing: border-box;
			cursor: pointer;
			line-height: 2.5;
			transition: 0.3s;
			font-size: 14px;

			&.active {
				background: #007aff;
				color: #fff;

				&:hover {
					background: #007aff;
					color: #fff;
				}
			}

			&:hover {
				background-color: #f5f5f5;
			}
		}

		.nosearch {
			font-size: 16px;
			line-height: 3;
			text-align: center;
			color: #666;
		}
	}
	.uni-select-lay-options-top {
		bottom: calc(100% + 5px);
	}
	.uni-select-lay-options-bottom {
		top: calc(100% + 5px);
	}
}

.rotating__animation {
	-webkit-animation: spin 1s linear 1s 5 alternate;
	animation: spin 1s linear infinite;
}

// 旋转
@-webkit-keyframes spin {
	from {
		-webkit-transform: rotate(0deg);
	}
	to {
		-webkit-transform: rotate(360deg);
	}
}

@keyframes spin {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

.mapFilter {
	display: flex;
	align-items: center;
	margin: 0 0 18rpx;
	padding: 20rpx;
	background: #ffffff;
	box-shadow: 0px 4rpx 13rpx 0px rgba(34, 23, 20, 0.1);
	border-radius: 10rpx;
	.mapIcon {
		width: 30rpx;
		height: 30rpx;
		margin-right: 10rpx;
	}
	&-label {
		padding: 10rpx;
		font-size: 26rpx;
		font-family: PingFang SC;
		font-weight: 500;
		color: #333333;
	}
	.line {
		width: 1px;
		height: 48rpx;
		background: #999999;
		opacity: 0.8;
		margin: 0 18rpx;
	}
	.iptBox {
		display: flex;
		flex: 1;
		.ipt {
			flex: 1;
			font-size: 26rpx;
			font-family: PingFang SC;
			font-weight: 400;
		}
	}
}
</style>
